package com.example.practice.common;

import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.Arrays;

/**
 * @BelongsProject: practice
 * @BelongsPackage: com.example.practice.common
 * @Author:
 * @CreateTime: 2020-09-03 19:07
 * @Description: 全局异常处理
 */
@Aspect
@Component
@Slf4j
@NoArgsConstructor
public class GlobalLoggingPrint {
    /**
     * 进入方法时间戳
     */
    private Long startTime;
    /**
     * 方法结束时间戳
     */
    private Long endTime;

    //切面
    @Pointcut("execution(public * com.woniuxy.cq.controller.*.*(..))")
    public void loggerOutPointcut() {

    }

    @Around("loggerOutPointcut()")
    public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
        // 接收到请求,取出请求域对象
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        //打印请求的内容
        startTime = System.currentTimeMillis();
        log.info("请求Url : {}", request.getRequestURL().toString());
        log.info("请求方式 : {}", request.getMethod());
        log.info("请求ip : {}", getIpAddr(request));
        log.info("请求控制器 : {}", pjp.getSignature().getDeclaringTypeName());
        log.info("请求方法 : {}", pjp.getSignature().getName());
        log.info("请求参数 : {}", Arrays.toString(pjp.getArgs()));
        // 执行方法
        Object result = pjp.proceed();
        log.info("请求结束时间：" + LocalDateTime.now());
        log.info("请求耗时：{}", (System.currentTimeMillis() - startTime) + "ms");
        // 处理完请求，返回内容
        log.info("请求返回 : {}", result);
        return result;
    }

    /*@AfterThrowing(value = "loggerOutPointcut()", throwing = "throwable")
    public void doAfterThrowing(Throwable throwable) {
        // 保存异常日志记录
        log.error("发生异常时间：{}", LocalDateTime.now());
        log.error("抛出异常：{}", throwable.getMessage());
    }*/

    /**
     * 描述 : 访问者ip的转换
     */
    public String getIpAddr(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        if ("0:0:0:0:0:0:0:1".equals(ip)) {
            ip = "127.0.0.1";
        }
        if (ip.split(",").length > 1) {
            ip = ip.split(",")[0];
        }
        return ip;
    }
}
